﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;

namespace Quebec.Logging.Services
{
	/// <summary>
	/// Do not use this class directly.
	/// All logging should go through the [Logger] class.
	/// The Logger class will use WCF to access the LoggingService.
	/// This class should remain internal. 
	/// This class is a singleton
	/// </summary>
	internal sealed class BaseLog
	{
		/// <summary>
		/// The default logger. This config file is controlling which appenders that this logger is using
		/// and the config file is also controlling the log level for this logger.
		/// </summary>
		private static readonly ILog _defaultLogger =
			LogManager.GetLogger("DefaultLogger");

		/// <summary>
		/// A special logger that cannot be disabled. This logger is not affected by the loglevel in the config files.
		/// This logger is used to log system events, that should always be logged (like when an emails has been sent).
		/// </summary>
		private static readonly ILog _persistentLogger =
		   LogManager.GetLogger("PersistentLogger");

		//const for log4net MDC
		private const string ApplicationName = "ApplicationName";

		/// <summary>
		/// The single instance
		/// </summary>
		private static readonly BaseLog _instance = new BaseLog();

		/// <summary>
		/// Returns the Singleton logger instance
		/// </summary>
		public static BaseLog Instance
		{
			get
			{
				return _instance;
			}
		}

		/// <summary>
		/// Static Constructor
		/// </summary>
		static BaseLog()
		{
			// Explicit static constructor to tell C# compiler
			// not to mark type as beforefieldinit
		}

		//private constructor since its a singleton            
		private BaseLog()
		{
		}

		private void SetMDCValue(string applicationName)
		{
			MDC.Set(ApplicationName, applicationName);
		}

		public void Debug(string applicationName, object message)
		{
			SetMDCValue(applicationName);
			_defaultLogger.Debug(message);
		}

		public void Info(string applicationName, object message)
		{
			SetMDCValue(applicationName);
			_persistentLogger.Info(message);
		}

		public void Error(string applicationName, object message)
		{
			SetMDCValue(applicationName);
			_defaultLogger.Error(message);
		}

		public void Warn(string applicationName, object message)
		{
			SetMDCValue(applicationName);
			_defaultLogger.Warn(message);
		}

		public void Fatal(string applicationName, object message)
		{
			SetMDCValue(applicationName);
			_defaultLogger.Fatal(message);
		}
	}
}
